package adapter

import (
	"fmt"
	sts "github.com/tencentyun/qcloud-cos-sts-sdk/go"
	"strings"
	"time"
)

type CosAdapter struct {
	CosConf
}

type CosConf struct {
	Appid     string `json:"appid"`
	SecretId  string `json:"secretId"`
	SecretKey string `json:"secretKey"`
	Storage   [] CosStorage `json:"storage"`
}


type CosStorage struct {
	Bucket   string `json:"bucket"`
	Region   string `json:"region"`
	Endpoint string `json:"endpoint"`
}


type CosTokenResp struct {
	ImgToken CosTokenItem `json:"img_token"`
}

type CosTokenItem struct {
	ExpiredTime int                     `json:"expiredTime"`
	Expiration  string                  `json:"expiration"`
	Credentials CosTokenItemCredentials `json:"credentials"`
	RequestId   string                  `json:"requestId"`
	StartTime   int                     `json:"startTime"`
	Timestamp   int                     `json:"timestamp"`
}

type CosTokenItemCredentials struct {
	SessionToken string `json:"sessionToken"`
	TmpSecretId  string `json:"tmpSecretId"`
	TmpSecretKey string `json:"tmpSecretKey"`
}

func (m *CosAdapter) getRegion(bucket string) string {
	for _, val := range m.Storage {
		if val.Bucket == bucket {
			return val.Region
		}
	}
	return ""
}

// ImgToken 获取上传凭证
func (m *CosAdapter) ImgToken( bucket, key string) (interface{}, error) {
	appid := m.Appid
	c := sts.NewClient(
		m.SecretId,
		m.SecretKey,
		nil,
		// sts.Host("sts.tencentcloudapi.com"), // 设置域名, 默认域名sts.tencentcloudapi.com
		// sts.Scheme("http"),      // 设置协议, 默认为https，公有云sts获取临时密钥不允许走http，特殊场景才需要设置http
	)
	opt := &sts.CredentialOptions{
		DurationSeconds: int64(time.Hour.Seconds()),
		Region:          m.getRegion(bucket),
		Policy: &sts.CredentialPolicy{
			Statement: []sts.CredentialPolicyStatement{
				{
					// 密钥的权限列表。简单上传和分片需要以下的权限，其他权限列表请看 https://cloud.tencent.com/document/product/436/31923
					Action: []string{
						// 简单上传
						"name/cos:PostObject",
						"name/cos:PutObject",
						// 分片上传
						"name/cos:InitiateMultipartUpload",
						"name/cos:ListMultipartUploads",
						"name/cos:ListParts",
						"name/cos:UploadPart",
						"name/cos:CompleteMultipartUpload",
					},
					Effect: "allow",
					Resource: []string{
						//这里改成允许的路径前缀，可以根据自己网站的用户登录态判断允许上传的具体路径，例子： a.jpg 或者 a/* 或者 * (使用通配符*存在重大安全风险, 请谨慎评估使用)
						"qcs::cos:"+m.getRegion(bucket)+":uid/" + appid + ":" + bucket + "/*",
					},
				},
			},
		},
	}

	// case 1 请求临时密钥
	res, err := c.GetCredential(opt)
	if err != nil {
		return nil, err
	}

	return &CosTokenResp{CosTokenItem{
		ExpiredTime: res.ExpiredTime,
		Expiration:  res.Expiration,
		Credentials: CosTokenItemCredentials{
			SessionToken: res.Credentials.SessionToken,
			TmpSecretId:  res.Credentials.TmpSecretID,
			TmpSecretKey: res.Credentials.TmpSecretKey,
		},
		RequestId: res.RequestId,
		StartTime: res.StartTime,
		Timestamp: res.StartTime,
	}}, nil
}

// ImgUrl 获取图片地址
func (m *CosAdapter) ImgUrl( bucket, key string) string {
	if endpoint, ok := m.FileConf()[bucket]; ok {
		return fmt.Sprintf("%s/%s", endpoint, key)
	}
	return ""
}

// FileConf 公共访问配置-腾讯云
func (m *CosAdapter) FileConf() map[string]string {
	bucketCfg := map[string]string{}
	for _, val := range m.Storage {
		bucketCfg[val.Bucket] = strings.TrimRight(val.Endpoint, "/")
	}
	return bucketCfg
}
